/**
 * 
 */
package de.cbf.cam.dsa.facet.armor.editor;

import java.beans.IndexedPropertyChangeEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.widgets.Control;

import de.cbf.cam.dsa.facet.armor.FacetArmor;
import de.cbf.cam.dsa.facet.armor.helper.ConstantsArmorZoneFactors;
import de.cbf.cam.dsa.facet.armor.helper.ZoneFactors;
import de.cbf.util.entity.facet.edit.composites.factorys.AbstractFacetSectionFactory;
import de.cbf.util.entity.facet.edit.controller.AbstractControllerEditFacet;
import de.cbf.util.ui.controller.ControllerTableEdit;
import de.cbf.util.ui.listener.IUiChangeListener;
import de.cbf.util.ui.listener.UiChangeEvent;

/**
 * @author Nebelritter
 *
 */
public class ControllerEditorFacetArmor extends AbstractControllerEditFacet<FacetArmor> {
	private static final Log logger = LogFactory.getLog(ControllerEditorFacetArmor.class);

	public static final String TEXT_STATE_EVENT_Be_ERROR				= "Be setting not correct";
	public static final String TEXT_STATE_EVENT_Be_WARNING				= FacetArmor.TEXT_UNSET_BE;
	public static final String TEXT_STATE_EVENT_RsAll_ERROR				= "RsAll setting not correct";
	public static final String TEXT_STATE_EVENT_RsAll_WARNING			= FacetArmor.TEXT_UNSET_RS_ALL;
	public static final String TEXT_STATE_EVENT_RsHead_ERROR			= "RsHead setting not correct";
	public static final String TEXT_STATE_EVENT_RsHead_WARNING			= FacetArmor.TEXT_UNSET_RS_HEAD;
	public static final String TEXT_STATE_EVENT_RsChest_ERROR			= "RsChest setting not correct";
	public static final String TEXT_STATE_EVENT_RsChest_WARNING			= FacetArmor.TEXT_UNSET_RS_CHEST;
	public static final String TEXT_STATE_EVENT_RsBack_ERROR			= "RsBack setting not correct";
	public static final String TEXT_STATE_EVENT_RsBack_WARNING			= FacetArmor.TEXT_UNSET_RS_BACK;
	public static final String TEXT_STATE_EVENT_RsStomach_ERROR			= "RsStomach setting not correct";
	public static final String TEXT_STATE_EVENT_RsStomach_WARNING		= FacetArmor.TEXT_UNSET_RS_STOMACH;
	public static final String TEXT_STATE_EVENT_RsArmLeft_ERROR			= "RsArmLeft setting not correct";
	public static final String TEXT_STATE_EVENT_RsArmLeft_WARNING		= FacetArmor.TEXT_UNSET_RS_ARM_LEFT;
	public static final String TEXT_STATE_EVENT_RsArmRight_ERROR		= "RsArmRight setting not correct";
	public static final String TEXT_STATE_EVENT_RsArmRight_WARNING		= FacetArmor.TEXT_UNSET_RS_ARM_RIGHT;
	public static final String TEXT_STATE_EVENT_RsLegLeft_ERROR			= "RsLegLeft setting not correct";
	public static final String TEXT_STATE_EVENT_RsLegLeft_WARNING		= FacetArmor.TEXT_UNSET_RS_LEG_LEFT;
	public static final String TEXT_STATE_EVENT_RsLegRight_ERROR		= "RsLegRight setting not correct";
	public static final String TEXT_STATE_EVENT_RsLegRight_WARNING		= FacetArmor.TEXT_UNSET_RS_LEG_RIGHT;
	public static final String TEXT_STATE_EVENT_ZoneDividerRS_ERROR		= "ZoneDividerRS setting not correct";
	public static final String TEXT_STATE_EVENT_ZoneDividerRS_WARNING	= FacetArmor.TEXT_UNSET_ZONE_DIVIDER_RS;
	public static final String TEXT_STATE_EVENT_ZoneDividerBE_ERROR		= "ZoneDividerBE setting not correct";
	public static final String TEXT_STATE_EVENT_ZoneDividerBE_WARNING	= FacetArmor.TEXT_UNSET_ZONE_DIVIDER_BE;
	public static final String TEXT_STATE_EVENT_Stars_ERROR				= "Stars setting not correct";
	public static final String TEXT_STATE_EVENT_Stars_WARNING			= FacetArmor.TEXT_UNSET_STARS;
	
	protected static final StateEvent STATE_EVENT_Be_ERROR 	 				= new StateEvent(TEXT_STATE_EVENT_Be_ERROR, StateEvent.STATE_ERROR);
	protected static final StateEvent STATE_EVENT_Be_WARNING 				= new StateEvent(TEXT_STATE_EVENT_Be_WARNING, StateEvent.STATE_WARNING);
	protected static final StateEvent STATE_EVENT_RsAll_ERROR 				= new StateEvent(TEXT_STATE_EVENT_RsAll_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_RsAll_WARNING				= new StateEvent(TEXT_STATE_EVENT_RsAll_WARNING, StateEvent.STATE_WARNING); 
	protected static final StateEvent STATE_EVENT_RsHead_ERROR 				= new StateEvent(TEXT_STATE_EVENT_RsHead_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_RsHead_WARNING			= new StateEvent(TEXT_STATE_EVENT_RsHead_WARNING, StateEvent.STATE_WARNING); 
	protected static final StateEvent STATE_EVENT_RsChest_ERROR 			= new StateEvent(TEXT_STATE_EVENT_RsChest_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_RsChest_WARNING			= new StateEvent(TEXT_STATE_EVENT_RsChest_WARNING, StateEvent.STATE_WARNING); 
	protected static final StateEvent STATE_EVENT_RsBack_ERROR 				= new StateEvent(TEXT_STATE_EVENT_RsBack_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_RsBack_WARNING			= new StateEvent(TEXT_STATE_EVENT_RsBack_WARNING, StateEvent.STATE_WARNING); 
	protected static final StateEvent STATE_EVENT_RsStomach_ERROR 			= new StateEvent(TEXT_STATE_EVENT_RsStomach_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_RsStomach_WARNING			= new StateEvent(TEXT_STATE_EVENT_RsStomach_WARNING, StateEvent.STATE_WARNING); 
	protected static final StateEvent STATE_EVENT_RsArmLeft_ERROR 			= new StateEvent(TEXT_STATE_EVENT_RsArmLeft_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_RsArmLeft_WARNING			= new StateEvent(TEXT_STATE_EVENT_RsArmLeft_WARNING, StateEvent.STATE_WARNING); 
	protected static final StateEvent STATE_EVENT_RsArmRight_ERROR 			= new StateEvent(TEXT_STATE_EVENT_RsArmRight_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_RsArmRight_WARNING		= new StateEvent(TEXT_STATE_EVENT_RsArmRight_WARNING, StateEvent.STATE_WARNING); 
	protected static final StateEvent STATE_EVENT_RsLegLeft_ERROR 			= new StateEvent(TEXT_STATE_EVENT_RsLegLeft_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_RsLegLeft_WARNING			= new StateEvent(TEXT_STATE_EVENT_RsLegLeft_WARNING, StateEvent.STATE_WARNING); 
	protected static final StateEvent STATE_EVENT_RsLegRight_ERROR 			= new StateEvent(TEXT_STATE_EVENT_RsLegRight_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_RsLegRight_WARNING		= new StateEvent(TEXT_STATE_EVENT_RsLegRight_WARNING, StateEvent.STATE_WARNING); 
	protected static final StateEvent STATE_EVENT_ZoneDivider_ERROR_RS		= new StateEvent(TEXT_STATE_EVENT_ZoneDividerRS_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_ZoneDivider_WARNING_RS	= new StateEvent(TEXT_STATE_EVENT_ZoneDividerRS_WARNING, StateEvent.STATE_WARNING); 
	protected static final StateEvent STATE_EVENT_ZoneDivider_ERROR_BE 		= new StateEvent(TEXT_STATE_EVENT_ZoneDividerBE_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_ZoneDivider_WARNING_BE	= new StateEvent(TEXT_STATE_EVENT_ZoneDividerBE_WARNING, StateEvent.STATE_WARNING);
	protected static final StateEvent STATE_EVENT_Stars_ERROR 				= new StateEvent(TEXT_STATE_EVENT_Stars_ERROR, StateEvent.STATE_ERROR); 	
	protected static final StateEvent STATE_EVENT_Stars_WARNING				= new StateEvent(TEXT_STATE_EVENT_Stars_WARNING, StateEvent.STATE_WARNING); 
	
	public static final Double UNSET_CALCULATED_ARMOR_VALUE = 0D;
	
	protected CompositeEditArmor 	compositeEditArmor;

	protected NumberFormat format;
		
	protected Double calculatedArmorValue; //transient, only to optimize calculation
	
	@Override
	protected void init() {
		super.init();
		format = NumberFormat.getInstance();
		pclFacetArmor = new PCLFacetArmor();
		uilFacetArmor = new UILFacetArmor();
		//
		calculatedArmorValue = UNSET_CALCULATED_ARMOR_VALUE;
	}
	
	@Override
	protected AbstractFacetSectionFactory createSectionFactory() {		
		return new SectionFactoryArmor();
	}

	@Override
	protected FacetArmor createNewFacet() {		
		return new FacetArmor();
	}

	@Override
	public Class<FacetArmor> getFacetClass() {		
		return FacetArmor.class;
	}

	public Double calculateArmorValue(){
		//calculate only if unset
		if(calculatedArmorValue == UNSET_CALCULATED_ARMOR_VALUE){
			ZoneFactors factors = facet.getZoneFactors();
			//add rs with factors
			calculatedArmorValue += factors.getZoneFactor(ConstantsArmorZoneFactors.ZONE_HEAD)		* facet.getRsHead();
			calculatedArmorValue += factors.getZoneFactor(ConstantsArmorZoneFactors.ZONE_CHEST)		* facet.getRsChest();
			calculatedArmorValue += factors.getZoneFactor(ConstantsArmorZoneFactors.ZONE_BACK)		* facet.getRsBack();
			calculatedArmorValue += factors.getZoneFactor(ConstantsArmorZoneFactors.ZONE_STOMACH)		* facet.getRsStomach();
			calculatedArmorValue += factors.getZoneFactor(ConstantsArmorZoneFactors.ZONE_ARM_LEFT)	* facet.getRsArmLeft();
			calculatedArmorValue += factors.getZoneFactor(ConstantsArmorZoneFactors.ZONE_ARM_RIGHT)	* facet.getRsArmRight();
			calculatedArmorValue += factors.getZoneFactor(ConstantsArmorZoneFactors.ZONE_LEG_LEFT)	* facet.getRsLegLeft();
			calculatedArmorValue += factors.getZoneFactor(ConstantsArmorZoneFactors.ZONE_LEG_RIGHT)	* facet.getRsLegRight();
		}		
		return calculatedArmorValue;
	}
	
	public void calculateBeZones(){
		Double armorValue = calculateArmorValue();
		Double result = armorValue / facet.getZoneDividerBE();		
		//subtract stars
		result -= facet.getStars();
		
		facet.setBeZones(result);
	}
	
	public void calculateRsAllZones(){
		//do not calculate if no zone divider is set
		if(facet.getZoneDividerRS() != FacetArmor.UNSET_ZONE_DIVIDER_RS){
			calculatedArmorValue = UNSET_CALCULATED_ARMOR_VALUE;
			Double armorValue = calculateArmorValue();
			Double result = armorValue / facet.getZoneDividerRS();
			facet.setRsAllZones(result);
		}		
	}
	
	public void modifyBe(String newBe) {
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationBeStatus(false);
			}			
			removeStateEvent(STATE_EVENT_Be_ERROR);
			valueNumber =  format.parse(newBe);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setBe(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationBeStatus(true);	
			}
			addStateEvent(STATE_EVENT_Be_ERROR);			
		}	
	}
	
	public void modifyRsAll(String newRsAll) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsAllStatus(false);
			}
			removeStateEvent(STATE_EVENT_RsAll_ERROR);
			valueNumber =  format.parse(newRsAll);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setRsAll(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsAllStatus(true);	
			}
			addStateEvent(STATE_EVENT_RsAll_ERROR);			
		}	
	}
	
	public void modifyRsHead(String newRsHead) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsHeadStatus(false);
			}
			removeStateEvent(STATE_EVENT_RsHead_ERROR);
			valueNumber =  format.parse(newRsHead);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setRsHead(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsHeadStatus(true);	
			}
			addStateEvent(STATE_EVENT_RsHead_ERROR);			
		}	
	}
	
	public void modifyRsChest(String newRsChest) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsChestStatus(false);
			}
			removeStateEvent(STATE_EVENT_RsChest_ERROR);
			valueNumber =  format.parse(newRsChest);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setRsChest(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsChestStatus(true);	
			}
			addStateEvent(STATE_EVENT_RsChest_ERROR);			
		}	
	}
	
	public void modifyRsBack(String newRsBack) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsBackStatus(false);
			}
			removeStateEvent(STATE_EVENT_RsBack_ERROR);
			valueNumber =  format.parse(newRsBack);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setRsBack(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsBackStatus(true);	
			}
			addStateEvent(STATE_EVENT_RsBack_ERROR);			
		}	
	}
	
	public void modifyRsStomach(String newRsStomach) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsStomachStatus(false);
			}
			removeStateEvent(STATE_EVENT_RsStomach_ERROR);
			valueNumber =  format.parse(newRsStomach);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setRsStomach(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsStomachStatus(true);	
			}
			addStateEvent(STATE_EVENT_RsStomach_ERROR);			
		}	
	}
	
	public void modifyRsArmLeft(String newRsArmLeft) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsArmLeftStatus(false);
			}
			removeStateEvent(STATE_EVENT_RsArmLeft_ERROR);
			valueNumber =  format.parse(newRsArmLeft);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setRsArmLeft(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsArmLeftStatus(true);	
			}
			addStateEvent(STATE_EVENT_RsArmLeft_ERROR);			
		}	
	}
	
	public void modifyRsArmRight(String newRsArmRight) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsArmRightStatus(false);
			}
			removeStateEvent(STATE_EVENT_RsArmRight_ERROR);
			valueNumber =  format.parse(newRsArmRight);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setRsArmRight(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsArmRightStatus(true);	
			}
			addStateEvent(STATE_EVENT_RsArmRight_ERROR);			
		}	
	}
	
	public void modifyRsLegLeft(String newRsLegLeft) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsLegLeftStatus(false);
			}
			removeStateEvent(STATE_EVENT_RsLegLeft_ERROR);
			valueNumber =  format.parse(newRsLegLeft);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setRsLegLeft(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsLegLeftStatus(true);	
			}
			addStateEvent(STATE_EVENT_RsLegLeft_ERROR);			
		}	
	}
	
	public void modifyRsLegRight(String newRsLegRight) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsLegRightStatus(false);
			}
			removeStateEvent(STATE_EVENT_RsLegRight_ERROR);
			valueNumber =  format.parse(newRsLegRight);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setRsLegRight(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationRsLegRightStatus(true);	
			}
			addStateEvent(STATE_EVENT_RsLegRight_ERROR);			
		}	
	}
		
	public void modifyZoneDividerRS(String newZoneDividerRS) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationZoneDividerRSStatus(false);
			}
			removeStateEvent(STATE_EVENT_ZoneDivider_ERROR_RS);
			valueNumber =  format.parse(newZoneDividerRS);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setZoneDividerRS(valueLong.doubleValue());
			}
			if (valueNumber instanceof Double) {
				Double valueDouble = (Double) valueNumber;
				facet.setZoneDividerRS(valueDouble);
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationZoneDividerRSStatus(true);	
			}
			addStateEvent(STATE_EVENT_ZoneDivider_ERROR_RS);			
		}	
	}
	
	public void modifyZoneDividerBE(String newZoneDividerBE) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationZoneDividerBEStatus(false);
			}
			removeStateEvent(STATE_EVENT_ZoneDivider_ERROR_BE);
			valueNumber =  format.parse(newZoneDividerBE);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setZoneDividerBE(valueLong.doubleValue());
			}
			if (valueNumber instanceof Double) {
				Double valueDouble = (Double) valueNumber;
				facet.setZoneDividerBE(valueDouble);
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationZoneDividerBEStatus(true);	
			}
			addStateEvent(STATE_EVENT_ZoneDivider_ERROR_BE);			
		}	
	}
	
	public void modifyStars(String newStars) {	
		if(facet == null) return;	
		Number valueNumber;
		try {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationStarsStatus(false);
			}
			removeStateEvent(STATE_EVENT_Stars_ERROR);
			valueNumber =  format.parse(newStars);		
			if (valueNumber instanceof Long) {
				Long valueLong = (Long) valueNumber;
				facet.setStars(valueLong.intValue());
			}
		} catch (ParseException e) {
			if(compositeEditArmor != null){
				compositeEditArmor.setDecorationStarsStatus(true);	
			}
			addStateEvent(STATE_EVENT_Stars_ERROR);			
		}	
	}
	
	public void updateBeZones(Double newBeZones) {
		if(newBeZones != null && compositeEditArmor != null){
			if( ! newBeZones.equals(FacetArmor.UNSET_BE_ZONES)){				
				compositeEditArmor.setBeZones(format.format(newBeZones));				
			}else{
				compositeEditArmor.setBeZones("");				
			}				
		}			
	}	
	
	public void updateRsAllZones(Double newRsAllZones) {
		if(newRsAllZones != null && compositeEditArmor != null){
			if( ! newRsAllZones.equals(FacetArmor.UNSET_RS_ALL_ZONES)){
				compositeEditArmor.setRsAllZones(format.format(newRsAllZones));
			}else{
				compositeEditArmor.setRsAllZones("");
			}				
		}			
	}
	
	public void updateBe(Integer newBe) {
		if(newBe != null && compositeEditArmor != null){
			if( ! newBe.equals(FacetArmor.UNSET_BE)){				
				compositeEditArmor.setBe(format.format(newBe));
				removeStateEvent(STATE_EVENT_Be_WARNING);
			}else{
				compositeEditArmor.setBe("");
				addStateEvent(STATE_EVENT_Be_WARNING);
			}				
		}			
	}
		
	public void updateRsAll(Integer newRsAll) {
		if(newRsAll != null && compositeEditArmor != null){
			if( ! newRsAll.equals(FacetArmor.UNSET_RS_ALL)){				
				compositeEditArmor.setRsAll(format.format(newRsAll));
				removeStateEvent(STATE_EVENT_RsAll_WARNING);
			}else{
				compositeEditArmor.setRsAll("");
				addStateEvent(STATE_EVENT_RsAll_WARNING);
			}				
		}			
	}
	
	public void updateRsHead(Integer newRsHead) {
		if(newRsHead != null && compositeEditArmor != null){
			if( ! newRsHead.equals(FacetArmor.UNSET_RS_HEAD)){				
				compositeEditArmor.setRsHead(format.format(newRsHead));
				removeStateEvent(STATE_EVENT_RsHead_WARNING);
			}else{
				compositeEditArmor.setRsHead("");
				addStateEvent(STATE_EVENT_RsHead_WARNING);
			}				
		}			
	}
	
	public void updateRsChest(Integer newRsChest) {
		if(newRsChest != null && compositeEditArmor != null){
			if( ! newRsChest.equals(FacetArmor.UNSET_RS_CHEST)){				
				compositeEditArmor.setRsChest(format.format(newRsChest));
				removeStateEvent(STATE_EVENT_RsChest_WARNING);
			}else{
				compositeEditArmor.setRsChest("");
				addStateEvent(STATE_EVENT_RsChest_WARNING);
			}				
		}			
	}
		
	public void updateRsBack(Integer newRsBack) {
		if(newRsBack != null && compositeEditArmor != null){
			if( ! newRsBack.equals(FacetArmor.UNSET_RS_BACK)){				
				compositeEditArmor.setRsBack(format.format(newRsBack));
				removeStateEvent(STATE_EVENT_RsBack_WARNING);
			}else{
				compositeEditArmor.setRsBack("");
				addStateEvent(STATE_EVENT_RsBack_WARNING);
			}				
		}			
	}
		
	public void updateRsStomach(Integer newRsStomach) {
		if(newRsStomach != null && compositeEditArmor != null){
			if( ! newRsStomach.equals(FacetArmor.UNSET_RS_STOMACH)){				
				compositeEditArmor.setRsStomach(format.format(newRsStomach));
				removeStateEvent(STATE_EVENT_RsStomach_WARNING);
			}else{
				compositeEditArmor.setRsStomach("");
				addStateEvent(STATE_EVENT_RsStomach_WARNING);
			}				
		}			
	}
	
	public void updateRsArmLeft(Integer newRsArmLeft) {
		if(newRsArmLeft != null && compositeEditArmor != null){
			if( ! newRsArmLeft.equals(FacetArmor.UNSET_RS_ARM_LEFT)){				
				compositeEditArmor.setRsArmLeft(format.format(newRsArmLeft));
				removeStateEvent(STATE_EVENT_RsArmLeft_WARNING);
			}else{
				compositeEditArmor.setRsArmLeft("");
				addStateEvent(STATE_EVENT_RsArmLeft_WARNING);
			}				
		}			
	}
	
	public void updateRsArmRight(Integer newRsArmRight) {
		if(newRsArmRight != null && compositeEditArmor != null){
			if( ! newRsArmRight.equals(FacetArmor.UNSET_RS_ARM_RIGHT)){				
				compositeEditArmor.setRsArmRight(format.format(newRsArmRight));
				removeStateEvent(STATE_EVENT_RsArmRight_WARNING);
			}else{
				compositeEditArmor.setRsArmRight("");
				addStateEvent(STATE_EVENT_RsArmRight_WARNING);
			}				
		}			
	}
	
	public void updateRsLegLeft(Integer newRsLegLeft) {
		if(newRsLegLeft != null && compositeEditArmor != null){
			if( ! newRsLegLeft.equals(FacetArmor.UNSET_RS_LEG_LEFT)){				
				compositeEditArmor.setRsLegLeft(format.format(newRsLegLeft));
				removeStateEvent(STATE_EVENT_RsLegLeft_WARNING);
			}else{
				compositeEditArmor.setRsLegLeft("");
				addStateEvent(STATE_EVENT_RsLegLeft_WARNING);
			}				
		}			
	}
	
	public void updateRsLegRight(Integer newRsLegRight) {
		if(newRsLegRight != null && compositeEditArmor != null){
			if( ! newRsLegRight.equals(FacetArmor.UNSET_RS_LEG_RIGHT)){				
				compositeEditArmor.setRsLegRight(format.format(newRsLegRight));
				removeStateEvent(STATE_EVENT_RsLegRight_WARNING);
			}else{
				compositeEditArmor.setRsLegRight("");
				addStateEvent(STATE_EVENT_RsLegRight_WARNING);
			}				
		}			
	}
	
	public void updateZoneDividerRS(Double newZoneDividerRS) {
		if(newZoneDividerRS != null && compositeEditArmor != null){
			if( ! newZoneDividerRS.equals(FacetArmor.UNSET_ZONE_DIVIDER_RS)){				
				compositeEditArmor.setZoneDividerRS(format.format(newZoneDividerRS));
				removeStateEvent(STATE_EVENT_ZoneDivider_WARNING_RS);
			}else{
				compositeEditArmor.setZoneDividerRS("");
				addStateEvent(STATE_EVENT_ZoneDivider_WARNING_RS);
			}				
		}			
	}
	
	public void updateZoneDividerBE(Double newZoneDividerBE) {
		if(newZoneDividerBE != null && compositeEditArmor != null){
			if( ! newZoneDividerBE.equals(FacetArmor.UNSET_ZONE_DIVIDER_BE)){				
				compositeEditArmor.setZoneDividerBE(format.format(newZoneDividerBE));
				removeStateEvent(STATE_EVENT_ZoneDivider_WARNING_BE);
			}else{
				compositeEditArmor.setZoneDividerBE("");
				addStateEvent(STATE_EVENT_ZoneDivider_WARNING_BE);
			}				
		}			
	}
		
	public void updateStars(Integer newStars) {
		if(newStars != null && compositeEditArmor != null){
			if( ! newStars.equals(FacetArmor.UNSET_STARS)){				
				compositeEditArmor.setStars(format.format(newStars));
				removeStateEvent(STATE_EVENT_Stars_WARNING);
			}else{
				compositeEditArmor.setStars("");
				addStateEvent(STATE_EVENT_Stars_WARNING);
			}				
		}			
	}
	
	@Override
	protected void updateAll(FacetArmor facet) {
		if(facet != null){
			updateBe(facet.getBe());
			updateBeZones(facet.getBeZones());
			updateRsAll(facet.getRsAll());
			updateRsAllZones(facet.getRsAllZones());
			updateRsHead(facet.getRsHead());
			updateRsChest(facet.getRsChest());
			updateRsBack(facet.getRsBack());
			updateRsStomach(facet.getRsStomach());
			updateRsArmLeft(facet.getRsArmLeft());
			updateRsArmRight(facet.getRsArmRight());
			updateRsLegLeft(facet.getRsLegLeft());
			updateRsLegRight(facet.getRsLegRight());
			updateZoneDividerRS(facet.getZoneDividerRS());
			updateZoneDividerBE(facet.getZoneDividerBE());
			updateStars(facet.getStars());
		}else{
			updateClearUI();
		}
	}	
	
	@Override
	protected void updateClearUI() {
		updateBe(FacetArmor.UNSET_BE);
		updateBeZones(FacetArmor.UNSET_BE_ZONES);
		updateRsAll(FacetArmor.UNSET_RS_ALL);
		updateRsAllZones(FacetArmor.UNSET_RS_ALL_ZONES);
		updateRsHead(FacetArmor.UNSET_RS_HEAD);
		updateRsChest(FacetArmor.UNSET_RS_CHEST);
		updateRsBack(FacetArmor.UNSET_RS_BACK);
		updateRsStomach(FacetArmor.UNSET_RS_STOMACH);
		updateRsArmLeft(FacetArmor.UNSET_RS_ARM_LEFT);
		updateRsArmRight(FacetArmor.UNSET_RS_ARM_RIGHT);
		updateRsLegLeft(FacetArmor.UNSET_RS_LEG_LEFT);
		updateRsLegRight(FacetArmor.UNSET_RS_LEG_RIGHT);
		updateZoneDividerRS(FacetArmor.UNSET_ZONE_DIVIDER_RS);
		updateZoneDividerBE(FacetArmor.UNSET_ZONE_DIVIDER_BE);
		updateStars(FacetArmor.UNSET_STARS);
	}
	
	@Override
	protected void preSetSection() {
		super.preSetSection();
		if(section != null){
			Control client = section.getClient();
			if (client instanceof CompositeEditArmor) {
				compositeEditArmor = (CompositeEditArmor) client;
				getControllerZoneFactors().setComposite(null);
				deRegisterUIListeners(compositeEditArmor);
			}else{
				logger.error("wrong client in section: expected "+CompositeEditArmor.class.getSimpleName()+
						" got: "+client.getClass().getSimpleName());
			}
		}
	}

	@Override
	protected void postSetSection() {
		super.postSetSection();
		Control client = section.getClient();
		if (client instanceof CompositeEditArmor) {
			compositeEditArmor = (CompositeEditArmor) client;
			registerUIListeners(compositeEditArmor);
			getControllerZoneFactors().setComposite(compositeEditArmor.getCompositeZoneFactors());
		}else{
			logger.error("wrong client in section: expected "+CompositeEditArmor.class.getSimpleName()+
					" got: "+client.getClass().getSimpleName());
		}
	}

	protected void registerUIListeners(CompositeEditArmor compositeEditArmor) {
		compositeEditArmor.registerUIListener(uilFacetArmor);
	}

	protected void deRegisterUIListeners(CompositeEditArmor compositeEditArmor) {
		compositeEditArmor.deRegisterUIListener(uilFacetArmor);
	}

	@Override
	protected void preSetNewFacet() {
		super.preSetNewFacet();
		if(facet != null){
			deRegisterModelListeners(facet);			
			controllerEditZoneFactors.setData(null);
		}
	}

	@Override
	protected void postSetNewFacet() {
		super.postSetNewFacet();
		if(facet != null){
			//initialize sub controller
			Collection<ZoneFactors> zoneFactors = new ArrayList<ZoneFactors>();
			zoneFactors.add(facet.getZoneFactors());
			controllerEditZoneFactors.setData(zoneFactors);
			//
			registerModelListeners(facet);			
		}
	}

	protected void registerModelListeners(FacetArmor facet) {
		facet.getPropertyChangeSupport().addPropertyChangeListener(pclFacetArmor);
	}

	protected void deRegisterModelListeners(FacetArmor facet) {
		facet.getPropertyChangeSupport().removePropertyChangeListener(pclFacetArmor);
	}
	
	
	
	protected UILFacetArmor uilFacetArmor;
	protected class UILFacetArmor implements IUiChangeListener{
		@Override
		public void uiChanged(UiChangeEvent event) {
			int index = event.getIndex();
			switch (index) {
				case CompositeEditArmor.EVT_EDIT_BE:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyBe(newValue);
					}
					break;
				}				
				case CompositeEditArmor.EVT_EDIT_RS_ALL:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyRsAll(newValue);
					}
					break;
				}				
				case CompositeEditArmor.EVT_EDIT_RS_HEAD:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyRsHead(newValue);
					}
					break;
				}
				case CompositeEditArmor.EVT_EDIT_RS_CHEST:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyRsChest(newValue);
					}
					break;
				}
				case CompositeEditArmor.EVT_EDIT_RS_BACK:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyRsBack(newValue);
					}
					break;
				}
				case CompositeEditArmor.EVT_EDIT_RS_STOMACH:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyRsStomach(newValue);
					}
					break;
				}
				case CompositeEditArmor.EVT_EDIT_RS_ARM_LEFT:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyRsArmLeft(newValue);
					}
					break;
				}
				case CompositeEditArmor.EVT_EDIT_RS_ARM_RIGHT:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyRsArmRight(newValue);
					}
					break;
				}
				case CompositeEditArmor.EVT_EDIT_RS_LEG_LEFT:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyRsLegLeft(newValue);
					}
					break;
				}
				case CompositeEditArmor.EVT_EDIT_RS_LEG_RIGHT:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyRsLegRight(newValue);
					}
					break;
				}
				case CompositeEditArmor.EVT_EDIT_ZONE_DIVIDER_RS:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyZoneDividerRS(newValue);
					}
					break;
				}
				case CompositeEditArmor.EVT_EDIT_ZONE_DIVIDER_BE:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyZoneDividerBE(newValue);
					}
					break;
				}
				case CompositeEditArmor.EVT_EDIT_STARS:{
					Object obj = event.getNewValue();
					if (obj instanceof String) {
						String newValue = (String) obj;
						modifyStars(newValue);
					}
					break;
				}
				default:
					logger.warn("unknown UI Change, index: "+index);					
					break;
			}
		}

		@Override
		public void commandIssued(int index, Object... parameters) {
			//not used
		}
	}

	protected PCLFacetArmor pclFacetArmor;
	protected class PCLFacetArmor implements PropertyChangeListener{
		@Override
		public void propertyChange(PropertyChangeEvent evt) {
			if (evt instanceof IndexedPropertyChangeEvent) {
				IndexedPropertyChangeEvent idxEvt = (IndexedPropertyChangeEvent) evt;
				int index = idxEvt.getIndex();
				if(index <= 4) return; //ignore indexes of NamedEntity and "below"
				switch (index) {
					case FacetArmor.PI_BE:{
						if (idxEvt.getNewValue() instanceof Integer) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateBe(value);
						}
						break;
					}
					case FacetArmor.PI_BE_ZONES:{
						if (idxEvt.getNewValue() instanceof Double) {
							Double value = (Double) idxEvt.getNewValue();
							updateBeZones(value);
						}						
						break;
					}
					case FacetArmor.PI_RS_ALL:{
						if (idxEvt.getNewValue() instanceof Long) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateRsAll(value);
						}
						break;
					}
					case FacetArmor.PI_RS_ALL_ZONES:{
						if (idxEvt.getNewValue() instanceof Double) {
							Double value = (Double) idxEvt.getNewValue();
							updateRsAllZones(value);
						}
						calculateBeZones();
						break;
					}
					case FacetArmor.PI_RS_HEAD:{
						if (idxEvt.getNewValue() instanceof Integer) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateRsHead(value);
						}
						calculateRsAllZones();						
						break;
					}
					case FacetArmor.PI_RS_CHEST:{
						if (idxEvt.getNewValue() instanceof Integer) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateRsChest(value);
						}
						calculateRsAllZones();						
						break;
					}
					case FacetArmor.PI_RS_BACK:{
						if (idxEvt.getNewValue() instanceof Integer) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateRsBack(value);
						}
						calculateRsAllZones();						
						break;
					}
					case FacetArmor.PI_RS_STOMACH:{
						if (idxEvt.getNewValue() instanceof Integer) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateRsStomach(value);
						}
						calculateRsAllZones();						
						break;
					}
					case FacetArmor.PI_RS_ARM_LEFT:{
						if (idxEvt.getNewValue() instanceof Integer) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateRsArmLeft(value);
						}
						calculateRsAllZones();						
						break;
					}
					case FacetArmor.PI_RS_ARM_RIGHT:{
						if (idxEvt.getNewValue() instanceof Integer) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateRsArmRight(value);
						}
						calculateRsAllZones();
						break;
					}
					case FacetArmor.PI_RS_LEG_LEFT:{
						if (idxEvt.getNewValue() instanceof Integer) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateRsLegLeft(value);
						}
						calculateRsAllZones();						
						break;
					}
					case FacetArmor.PI_RS_LEG_RIGHT:{
						if (idxEvt.getNewValue() instanceof Integer) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateRsLegRight(value);
						}
						calculateRsAllZones();						
						break;
					}
					case FacetArmor.PI_ZONE_DIVIDER_RS:{
						if (idxEvt.getNewValue() instanceof Double) {
							Double value = (Double) idxEvt.getNewValue();
							updateZoneDividerRS(value);
						}
						calculateRsAllZones();
						break;
					}
					case FacetArmor.PI_ZONE_DIVIDER_BE:{
						if (idxEvt.getNewValue() instanceof Double) {
							Double value = (Double) idxEvt.getNewValue();
							updateZoneDividerBE(value);
						}					
						calculateBeZones();
						break;
					}
					case FacetArmor.PI_STARS:{
						if (idxEvt.getNewValue() instanceof Integer) {
							Integer value = (Integer) idxEvt.getNewValue();
							updateStars(value);
						}
						calculateBeZones();
						break;
					}
					case ZoneFactors.PI_Standard:{
						return; //ignore changing of standard
					}
					case ZoneFactors.PI_ZoneFactor:
					case ZoneFactors.PI_AllZoneFactors:{
						//both are dealt with in the same way
						calculateRsAllZones();
						calculateBeZones();
						break;
					}
					default:
						logger.error("unknown property change index encountered: "+index);
						break;
				}
			}
		}
	}
	
	protected ControllerEditZoneFactors controllerEditZoneFactors;
	
	protected ControllerTableEdit<ZoneFactors> getControllerZoneFactors(){
		if(controllerEditZoneFactors == null){
			controllerEditZoneFactors = new ControllerEditZoneFactors();			
		}
		return controllerEditZoneFactors;
	}	
}
